/*
	下载、解析（XML）、存储iTunes排行榜到Core Data。
 */

#import <UIKit/UIKit.h>
#import <libxml/tree.h>

@class iTunesRSSImporter, Song;

// iTunesRSSImporter委托协议
@protocol iTunesRSSImporterDelegate <NSObject>

@optional
// NSManagedObjectContext(托管对象上下文)保存数据到持久化存储时，发布一个通知：Notification
- (void)importerDidSave:(NSNotification *)saveNotification;
// 下载的RSS解析完成后，处理后续操作
- (void)importerDidFinishParsingData:(iTunesRSSImporter *)importer;
// 处理错误
- (void)importer:(iTunesRSSImporter *)importer didFailWithError:(NSError *)error;

@end


@interface iTunesRSSImporter : NSOperation {
@private
    id <iTunesRSSImporterDelegate> delegate;
	
    // libxml 解析器上下文
    xmlParserCtxtPtr context;
    NSURLConnection *rssConnection;
	
    // iTunesRSSImporter状态，用于退出循环
    BOOL done;
    // 状态变量，用于解析RSS时，是否忽略某个XML元素
    BOOL parsingASong;
	
    // 下面的状态变量用于处理从XML元素中的字符串数据。可能是比较昂贵的操作。
	// XML元素中的字符串数据可能会导致多个回调，因此字符串数据应该添加到一个缓存。
	// 当所有字符串获取到后，便输出为一个NSString，并将缓存重置。
    BOOL storingCharacters;
    NSMutableData *characterBuffer;
	
    // iTunesRSSImporter当前处理的某个歌曲(从RSS XML中取得)
    Song *currentSong;
	
    // 为后台操作队列启用的第二线程提供一个自动释放的缓冲池，并定时清空，以免占用过多内存 
    NSUInteger countForCurrentBatch;
    NSUInteger rankOfCurrentSong;
    NSAutoreleasePool *importPool;
	
	// 格式化歌曲的releaseDate
    NSDateFormatter *dateFormatter;
	
	// Core Data 堆栈属性
    NSManagedObjectContext *insertionContext;
    NSPersistentStoreCoordinator *persistentStoreCoordinator;
    NSEntityDescription *songEntityDescription;
	
	// 排行榜URL
    NSURL *iTunesURL;
}

@property (nonatomic, retain) NSURL *iTunesURL;
@property (nonatomic, assign) id <iTunesRSSImporterDelegate> delegate;
@property (nonatomic, retain) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@property (nonatomic, retain, readonly) NSManagedObjectContext *insertionContext;
@property (nonatomic, retain, readonly) NSEntityDescription *songEntityDescription;


// 尽管 NSURLConnection 被设计为异步调用，但是仍然会占用大量的CPU。
// 为了UI处理能够即时响应操作，NSURLConnection 应该从主线程中移除，在新的线程中运行。
// 虽然这样让代码变的复杂，但是任何涉及到与UI的交互都应该这么做。
// 
// 应用程序使用NSOperation的非同步（non-concurrent）的操作，因此需要重载main方法。
- (void)main;


@end
